package com.lagou.filter;

import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;

import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;


//@Activate(group = {CommonConstants.CONSUMER,CommonConstants.PROVIDER})
@Activate(group = {CommonConstants.CONSUMER})
public class DubboInvokeFilter implements Filter {

    //第一个放时延，第二个放时刻
    public static Queue<Long[]> methodADelayQueue = new ArrayBlockingQueue<>(2000);
    public static Queue<Long[]> methodBDelayQueue = new ArrayBlockingQueue<>(2000);
    public static Queue<Long[]> methodCDelayQueue = new ArrayBlockingQueue<>(2000);


    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        long startTime = System.currentTimeMillis();
        try {
            // 执行方法
            return invoker.invoke(invocation);
        } finally {
//            System.out.println("invoke time:"+(System.currentTimeMillis()-startTime) + "毫秒");
            long endTime = System.currentTimeMillis();
            long delayTime = endTime - startTime;
            //
            if ("methodA".equals(invocation.getMethodName())) {
//                System.out.println("yes");
                Long[] peek = methodADelayQueue.peek();
                if (peek == null) {
                    methodADelayQueue.offer(new Long[]{delayTime, endTime});
                } else if (endTime - peek[1] <= 60 * 1000) {
                    methodADelayQueue.offer(new Long[]{delayTime, endTime});
                } else {
                    methodADelayQueue.poll();
                    methodADelayQueue.offer(new Long[]{delayTime, endTime});
                }
            }

            if ("methodB".equals(invocation.getMethodName())) {
//                System.out.println("yes");
                Long[] peek = methodBDelayQueue.peek();
                if (peek == null) {
                    methodBDelayQueue.offer(new Long[]{delayTime, endTime});
                } else if (endTime - peek[1] <= 60 * 1000) {
                    methodBDelayQueue.offer(new Long[]{delayTime, endTime});
                } else {
                    methodBDelayQueue.poll();
                    methodBDelayQueue.offer(new Long[]{delayTime, endTime});
                }
            }

            if ("methodC".equals(invocation.getMethodName())) {
//                System.out.println("yes");
                Long[] peek = methodCDelayQueue.peek();
                if (peek == null) {
                    methodCDelayQueue.offer(new Long[]{delayTime, endTime});
                } else if (endTime - peek[1] <= 60 * 1000) {
                    methodCDelayQueue.offer(new Long[]{delayTime, endTime});
                } else {
                    methodCDelayQueue.poll();
                    methodCDelayQueue.offer(new Long[]{delayTime, endTime});
                }
            }

        }

    }

    public static Long getTopPercentileDelay(double percent, Queue<Long[]> queue) {
        List<Long> delayList = new ArrayList<>();
        for (Long[] longs : queue) {
            delayList.add(longs[0]);
        }
        Collections.sort(delayList);
        int ceil = (int) Math.ceil(delayList.size() * percent);
        if (ceil == 0) {
            return delayList.get(0);
        }
        return delayList.get(ceil - 1);

    }

    public static void main(String[] args) {
        Queue<Integer> queue = new PriorityQueue<>();
        queue.offer(5);
        queue.offer(6);
        queue.offer(7);
        queue.offer(7);
        queue.offer(7);

////        System.out.println(Arrays.toString(queue.toArray()));
//        queue.offer(8);
        queue.poll();
//        System.out.println(queue.peek());
        System.out.println(Arrays.toString(queue.toArray()));
        System.out.println(queue.size());

        for (Integer integer : queue) {
            System.out.println(integer);
        }

//        double a = 0.65;
//        System.out.println(Math.ceil(a));
//
//        List<Integer> list = new ArrayList<>();
//        list.add(4);
//        list.add(5);
//        list.add(6);
//        list.add(1);
//        list.add(2);
//        list.add(5);
//        Collections.sort(list);
//        System.out.println(list);

    }
}
